from python_basic.common.xcommon import sep
from python_basic.exercise.oop.mro.Person import Person
from python_basic.exercise.oop.mro.PersonShoot import PersonShoot
from python_basic.exercise.oop.mro.Student import Student

"""
to-do: add comments
"""


class Hero(PersonShoot, Student):

    @staticmethod
    def mro():
        return Hero, Student, PersonShoot, Person, object

    def __init__(self, name, skill):
        PersonShoot.__init__(self, name)
        Student.__init__(self, '999999', 'Student: ' + str(name))
        self.__skill = skill
        self.__name = f'Hero {name}'

    def __del__(self):
        PersonShoot.__del__(self)
        Student.__del__(self)
        print(f'Destructing Hero {self._Person__name} with skill {self.__skill}')

    def __str__(self):
        return PersonShoot.__str__(self) \
                + '\n' + Student.__str__(self) \
                + f'\n{{ Hero: skill={self.__skill} }}'

    def shoot(self):
        self.__neigong()
        count = 1000
        self.add_bullet(count)
        PersonShoot.shoot(self, count)
        print(f'Hero {self._Person__name} is shooting with unlimited bullets! This is called "{self.__skill}"')

    def __neigong(self):
        print(f'Hero "{self._Person__name}" is using his Nei Gong ...')

    def _secret(self, secret):
        sep('_secret start')
        self.__neigong()
        print(f'Hello "{self._Person__name}" has secret as "{secret}"')
        sep('_secret end')


if '__main__' == __name__:
    sep('Hero')
    print(Hero.__mro__)
    sep(label='lvbu')
    lvbu = Hero('吕布', '舞弄方天画戟')
    print(lvbu)
    print(lvbu.__dict__)
    lvbu.shoot()
    PersonShoot.shoot(lvbu, 10)

    lvbu._secret('Haha')

    # lvbu.__neigong()  # AttributeError: 'Hero' object has no attribute '__neigong'
    lvbu._Hero__neigong()

    lvbu.set_scores('Fighting', 99.99)
    lvbu.set_scores('Math', 60)
    lvbu.set_scores('Language', 59.99)
    print(lvbu.get_scores())
    print('In fact, his student name is "{}"'.format(lvbu._Student__name))
    print(lvbu)

    xiaoyi = PersonShoot('小一')


    def check_types(obj):
        sep(label=obj.get_name())
        print('Person:', isinstance(obj, Person))
        print('PersonShoot', isinstance(obj, PersonShoot))
        print('Student', isinstance(obj, Student))
        print('Hero', isinstance(obj, Hero))
        # print('Person, Student:', issubclass(obj, (Person, Student)))  # TypeError: issubclass() arg 1 must be a class

    check_types(lvbu)
    check_types(xiaoyi)


    def check_sub(cls):
        sep(label=repr(cls))
        print('name:', cls.__name__)
        print('mro:', cls.__mro__)
        print('object:', issubclass(cls, object))
        print('Person:', issubclass(cls, Person))
        print('PersonShoot:', issubclass(cls, PersonShoot))
        print('Student:', issubclass(cls, Student))
        print('Hero:', issubclass(cls, Hero))
        print('Person, Student:', issubclass(cls, (Person, Student)))


    check_sub(Hero)
    check_sub(PersonShoot)
    check_sub(Person)
    check_sub(Student)
    check_sub(object)

    sep(label='End of testing Hero')
